//Source file: D:\\test\\com\\ce\\pms\\house\\model\\BuildingDomain.java

package com.ce.pms.house.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.exception.BusinessException;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.model.IDomainObject;

/**
 * 实体:楼栋 关联表：HM_BUILDING
 */
@Entity
@Table(name = "HM_BUILDING")
public class BuildingDomain implements IDomainObject{

	/**
	 * 楼栋单元数上限值
	 */
	public static final Integer BUILDING_CELLCOUNT_UPPERLIMIT = SysrefcodeDO.CONSTANTS_TEN;

	/**
	 * 楼栋单元数下限值
	 */
	public static final Integer BUILDING_CELLCOUNT_LOWERLIMIT = SysrefcodeDO.CONSTANTS_ONE;

	/**
	 * 楼栋主键
	 */
	@Id
	@GeneratedValue
	@Column(name = "BUILDING_ID")
	private Long keyword;

	/**
	 * 楼盘 检索策略:lazy=true
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "AREA_ID", nullable = false)
	private AreaDomain area;

	/**
	 * 建设期 检索策略:lazy=true
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "PROJECT_ID", nullable = false)
	private ProjectDomain project;

	/**
	 * 楼栋名称
	 */
	@Column(name = "NAME", nullable = false, insertable = true, updatable = true, length = 80)
	private String name;

	/**
	 * 楼栋编号
	 */
	@Column(name = "SEQ_NO", nullable = true)
	private Integer seqNo;

	/**
	 * 楼宇地下层数
	 */
	@Column(name = "UNDERGROUND", nullable = true)
	private Integer underGround;

	/**
	 * 楼宇地上层数
	 */
	@Column(name = "OVERGROUND", nullable = true)
	private Integer overGround;

	/**
	 * 是否分单元 1是 0否
	 */
	@Column(name = "HAS_CELL", nullable = true, length = 1)
	private String hasCell;

	// /**
	// * 单元数
	// */
	//
	// private Short cells;

	/**
	 * 高度
	 */

	@Column(name = "HIGH", nullable = true, precision = 12, scale = 2)
	private Double high;

	/**
	 * 竣工日期
	 */
	@Temporal(TemporalType.DATE)
	@Column(name = "COMPLETE_DATE", nullable = true)
	private Date completeDate;

	/**
	 * 区域/位置
	 */
	@Column(name = "POSITION", nullable = true, length = 200)
	private String position;

	/**
	 * 住宅套数
	 */
	@Column(name = "RESI_NUMBER", nullable = true)
	private Integer resiNumber;

	/**
	 * 车库层
	 */
	@Column(name = "CARBARN", nullable = true, length = 30)
	private String carbarn;

	/**
	 * 商铺层
	 */
	@Column(name = "SHOP", nullable = true, length = 30)
	private String shop;

	/**
	 * 住宅层
	 */
	@Column(name = "HOME", nullable = true, length = 30)
	private String home;

	/**
	 * 建筑面积
	 */
	@Column(name = "BUILD_SIZE", nullable = true, precision = 12, scale = 2)
	private Double buildSize;

	/**
	 * 防火等级
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.EAGER)
	@JoinColumn(name = "SYS_REF_ID1", nullable = true)
	private SysrefcodeDO fireproofLevel;

	/**
	 * 抗震等级
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.EAGER)
	@JoinColumn(name = "SYS_REF_ID2", nullable = true)
	private SysrefcodeDO aseismeticLevel;

	/**
	 * 人防等级
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.EAGER)
	@JoinColumn(name = "SYS_REF_ID3", nullable = true)
	private SysrefcodeDO aerialDefenceLevel;

	/**
	 * 主要结构选型
	 */
	@Column(name = "FRAMEWORK", nullable = true, length = 50)
	private String framework;

	/**
	 * 备注
	 */
	@Column(name = "REMARK", nullable = true, length = 200)
	private String remark;

	/**
	 * 规划图 检索策略:lazy=false
	 */
	@OneToOne(cascade = {CascadeType.REMOVE}, fetch = FetchType.EAGER)
	@JoinColumn(name = "LAYOUT_IMAGE_ID", nullable = true)
	private ImageDomain layoutImage;

	 /**
	 * 平面图集合
	 * 检索策略:lazy=false
	 */
	 @OneToMany(cascade={CascadeType.REMOVE},fetch=FetchType.EAGER)
	 @JoinTable(name="HM_IMAGE_R_BUILDING",
			 joinColumns={@JoinColumn(name="BUILDING_ID")},
			 inverseJoinColumns={@JoinColumn(name="IMAGE_ID")}
	 )
	 private Set<ImageDomain> ichnographys = new HashSet<ImageDomain>();

	/**
	 * 检索策略:lazy=true 级联配置:cascade=all-delete-orphan
	 *
	 * 备注:根据hasCell,cells手动初始化.
	 */
	@OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "building")
	@org.hibernate.annotations.Cascade(value = {
			org.hibernate.annotations.CascadeType.DELETE_ORPHAN,
			org.hibernate.annotations.CascadeType.SAVE_UPDATE
	})
	private Set<HouseGrp> houseGrps = new HashSet<HouseGrp>();

	@Embedded
	private SysInfo sysInfo;

	/**
	 * @roseuid 484F3FA2038A
	 */
	public BuildingDomain() {
	}

	/**
	 * mini constructor
	 * @param area 楼盘
	 * @param project 建设期
	 * @param name 栋名
	 * @param sysInfo 系统信息
	 */
	public BuildingDomain(AreaDomain area,
			ProjectDomain project,
			String name,
			SysInfo sysInfo) {
		super();
		this.area = area;
		this.project = project;
		this.name = name;
		this.sysInfo = sysInfo;
	}

	/**************************************************
	 * Accessors and Modifiers
	 **************************************************/

	public SysrefcodeDO getAerialDefenceLevel() {
		return aerialDefenceLevel;
	}

	public void setAerialDefenceLevel(SysrefcodeDO aerialDefenceLevel) {
		this.aerialDefenceLevel = aerialDefenceLevel;
	}

	public AreaDomain getArea() {
		return area;
	}

	public void setArea(AreaDomain area) {
		this.area = area;
	}

	public SysrefcodeDO getAseismeticLevel() {
		return aseismeticLevel;
	}

	public void setAseismeticLevel(SysrefcodeDO aseismeticLevel) {
		this.aseismeticLevel = aseismeticLevel;
	}

	public Double getBuildSize() {
		return buildSize;
	}

	public void setBuildSize(Double buildSize) {
		this.buildSize = buildSize;
	}

	public Set<ImageDomain> getIchnographys() {
		return ichnographys;
	}

	public void setIchnographys(Set<ImageDomain> ichnographys) {
		this.ichnographys = ichnographys;
	}

	public String getCarbarn() {
		return carbarn;
	}

	public void setCarbarn(String carbarn) {
		this.carbarn = carbarn;
	}

	public Date getCompleteDate() {
		return completeDate;
	}

	public void setCompleteDate(Date completeDate) {
		this.completeDate = completeDate;
	}

	public SysrefcodeDO getFireproofLevel() {
		return fireproofLevel;
	}

	public void setFireproofLevel(SysrefcodeDO fireproofLevel) {
		this.fireproofLevel = fireproofLevel;
	}

	public String getFramework() {
		return framework;
	}

	public void setFramework(String framework) {
		this.framework = framework;
	}

	public String getHasCell() {
		return hasCell;
	}

	public void setHasCell(String hasCell) {
		this.hasCell = hasCell;
	}

	public Double getHigh() {
		return high;
	}

	public void setHigh(Double high) {
		this.high = high;
	}

	public String getHome() {
		return home;
	}

	public void setHome(String home) {
		this.home = home;
	}

	public Set<HouseGrp> getHouseGrps() {
		return houseGrps;
	}

	public void setHouseGrps(Set<HouseGrp> houseGrps) {
		this.houseGrps = houseGrps;
	}

	public Long getKeyword() {
		return keyword;
	}

	public void setKeyword(Long keyword) {
		this.keyword = keyword;
	}

	public ImageDomain getLayoutImage() {
		return layoutImage;
	}

	public void setLayoutImage(ImageDomain layoutImage) {
		this.layoutImage = layoutImage;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	public ProjectDomain getProject() {
		return project;
	}

	public void setProject(ProjectDomain project) {
		this.project = project;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Integer getResiNumber() {
		return resiNumber;
	}

	public void setResiNumber(Integer resiNumber) {
		this.resiNumber = resiNumber;
	}

	public Integer getSeqNo() {
		return seqNo;
	}

	public void setSeqNo(Integer seqNo) {
		this.seqNo = seqNo;
	}

	public String getShop() {
		return shop;
	}

	public void setShop(String shop) {
		this.shop = shop;
	}

	public Integer getOverGround() {
		return overGround;
	}

	public void setOverGround(Integer overGround) {
		this.overGround = overGround;
	}

	public Integer getUnderGround() {
		return underGround;
	}

	public void setUnderGround(Integer underGround) {
		this.underGround = underGround;
	}

	public SysInfo getSysInfo() {
		return sysInfo;
	}

	public void setSysInfo(SysInfo sysInfo) {
		this.sysInfo = sysInfo;
	}

	/**
	 * 功能描述:  建立楼栋单元 <br>
	 * @param amount
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-14  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void generationHouseGrp(Integer amount){

		if (BlankUtil.isBlank(amount)) {
			return;
		}

		//规定上下限值
		if (BUILDING_CELLCOUNT_LOWERLIMIT > amount || BUILDING_CELLCOUNT_UPPERLIMIT < amount ) {
			throw new BusinessException(
					"house:building_cellCount_upperlimit_exception,"
							+ BUILDING_CELLCOUNT_LOWERLIMIT + ":" + BUILDING_CELLCOUNT_UPPERLIMIT,
					BusinessException.WARNING);
		}
		//得到原有单元集合
		Set<HouseGrp> oldHouseGrps = this.getHouseGrps();
		Integer oldAmount = 0;//用于记录原有单元数
		Set<HouseGrp> newHouseGrps = new HashSet<HouseGrp>();

		if (!BlankUtil.isBlank(oldHouseGrps)) {
			oldAmount = oldHouseGrps.size();
			newHouseGrps.addAll(oldHouseGrps);//加入原单元集合
		}

		HouseGrp tempHouseGrp = null;
		int i = oldAmount;

		if (oldAmount < amount) {
			while (i < amount) {
				tempHouseGrp = new HouseGrp();
				tempHouseGrp.setBuilding(this);
				tempHouseGrp.setName(String.valueOf(++i));
				newHouseGrps.add(tempHouseGrp);
			}
		}else if (oldAmount > amount){
			Set<HouseGrp> tempHouseGrps = new HashSet<HouseGrp>();
			Iterator<HouseGrp> iter = null;
			while (i > amount) {
				iter = newHouseGrps.iterator();
				while (iter.hasNext()) {
					HouseGrp element = iter.next();
					if (String.valueOf(i).equals(element.getName())) {
						tempHouseGrps.add(element);//得到要移除的单元
					}
				}

				i--;
			}
			newHouseGrps.removeAll(tempHouseGrps);//
		}
		this.houseGrps.clear();
		this.houseGrps.addAll(newHouseGrps);
	}

	/**
	 *
	 * 功能描述: 判断必填项是否有值
	 *
	 * @author 付湘辉
	 * Created on:2008-7-11
	 *
	 * 修改原因：
	 * @return void 返回结果
	 */
	public void checkRequiredField(){
		if (this.area == null
				|| this.project == null
				|| this.name == null
				|| this.seqNo == null
				|| this.overGround == null
 //               || this.underGround == null
                || BlankUtil.isBlank(this.home)) {
			throw new BusinessException("common:mustFill_null_exception",
					BusinessException.WARNING);
		}

		if (this.overGround < 1 ) {
			throw new BusinessException("house:building_illegal_storey_number_exception",BusinessException.WARNING);
		}

		if (this.underGround!=null && this.underGround < 0) {
			throw new BusinessException("house:building_illegal_underGround_number_exception",BusinessException.WARNING);
		}
	}

	/**
	 * 功能描述: 楼层规则检查 <br>
	 *
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-7-18  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void checkStoreyRole(){
		if (this.overGround < 1 ) {
			throw new BusinessException("house:building_illegal_storey_number_exception",BusinessException.WARNING);
		}

		if (this.underGround!=null && this.underGround < 0) {
			throw new BusinessException("house:building_illegal_underGround_number_exception",BusinessException.WARNING);
		}

		Pattern pattern = Pattern.compile("\\A-?[1-9]\\d*"+SysInfo.SEPARATOR_COMMA+"-?[1-9]\\d*\\z");
		Matcher matcher = null;
		Integer homeFrom = null;//用于住宅层开始层
		Integer homeTo = null;//用于住宅层结束层
		Integer shopFrom = null;//用于商铺层开始层
		Integer shopTo = null;//用于商铺层结束层
		Integer carbarnFrom = null;//用于车库层开始层
		Integer carbarnTo = null;//用于车库层结束层

		Integer totalStoreys = null;//记录总楼层楼
		boolean carbarnIsNull = true;
		//住宅层范围不能为空值
		if (!BlankUtil.isBlank(this.home)) {
			matcher = pattern.matcher(this.home);
			if (!matcher.matches()) {
				throw new BusinessException("house:building_illegal_home_exception",BusinessException.WARNING);
			}

			String[] homes = this.home.split(SysInfo.SEPARATOR_COMMA);
			homeFrom = Integer.valueOf(homes[0]);
			homeTo = Integer.valueOf(homes[1]);
			if (homeFrom > homeTo) {
				//各楼层范围的起始层不能高于截止层
				throw new BusinessException("house:building_to_more_than_from_exception",BusinessException.WARNING);
			}
			if (homeTo > this.overGround) {
				//楼层范围设置超过允许的最高楼层
				throw new BusinessException("house:building_floors_set_too_large_exception",BusinessException.WARNING);
			}
			Integer totalHome = 0<homeTo&&0>homeFrom?homeTo-homeFrom:homeTo-homeFrom +1;//得到住宅层数量
			totalStoreys = totalHome;
		}else{
			throw new BusinessException("house:building_home_null_exception",BusinessException.WARNING);
		}

//暂不检要车库和商铺		//车库层不为空
//		if (!BlankUtil.isBlank(this.carbarn)) {
//			matcher = pattern.matcher(this.carbarn);
//			if (!matcher.matches()) {
//				throw new BusinessException("house:building_illegal_carbarn_exception",BusinessException.WARNING);
//			}
//			String[] carbarns = this.carbarn.split(SysInfo.SEPARATOR_COMMA);
//			carbarnFrom = Integer.valueOf(carbarns[0]);
//			carbarnTo = Integer.valueOf(carbarns[1]);
//
//			if (carbarnFrom > carbarnTo) {
//				throw new BusinessException("house:building_to_more_than_from_exception",BusinessException.WARNING);
//			}
//			if (carbarnTo > this.underGround+this.overGround) {
//				//楼层范围设置超过允许的最高楼层
//				throw new BusinessException("house:building_floors_set_too_large_exception",BusinessException.WARNING);
//			}
//			if (!(homeFrom > carbarnTo || carbarnFrom > homeTo)) {
//				//各楼层范围不能出现重叠交叉值
//				throw new BusinessException("house:building_storey_cross_exception",BusinessException.WARNING);
//			}
//			Integer totalCarbarn = 0<carbarnTo&&0>carbarnFrom?carbarnTo-carbarnFrom:carbarnTo-carbarnFrom+1;//得到车库层数量
//			totalStoreys += totalCarbarn;
//
//			carbarnIsNull = false;
//		}
//
//		//商铺层不为空
//		if (!BlankUtil.isBlank(this.shop)) {
//			matcher = pattern.matcher(this.shop);
//			if (!matcher.matches()) {
//				throw new BusinessException("house:building_illegal_carbarn_exception",BusinessException.WARNING);
//			}
//			String[] shops = this.shop.split(SysInfo.SEPARATOR_COMMA);
//			shopFrom = Integer.valueOf(shops[0]);
//			shopTo = Integer.valueOf(shops[1]);
//			if (shopFrom > shopTo) {
//				throw new BusinessException("house:building_to_more_than_from_exception",BusinessException.WARNING);
//			}
//			if (shopTo > this.underGround+this.overGround) {
//				//楼层范围设置超过允许的最高楼层
//				throw new BusinessException("house:building_floors_set_too_large_exception",BusinessException.WARNING);
//			}
//			if (!(homeFrom > shopTo || shopFrom > homeTo)) {
//				//各楼层范围不能出现重叠交叉值
//				throw new BusinessException("house:building_storey_cross_exception",BusinessException.WARNING);
//			}
//			if (!carbarnIsNull) {
//				if (!(carbarnFrom > shopTo || shopFrom > carbarnTo)) {
//					throw new BusinessException("house:building_storey_cross_exception",BusinessException.WARNING);
//				}
//			}
//			Integer totalShop = 0<shopTo&&0>shopFrom? shopTo-shopFrom:shopTo-shopFrom+1;//得到商铺层数量
//			totalStoreys += totalShop;
//		}
//
//		if (totalStoreys > this.underGround+this.overGround) {
//			//楼层范围设置超过允许的最高楼层
//			throw new BusinessException("house:building_floors_set_too_large_exception",BusinessException.WARNING);
//		}
	}

}
